package cn.hx.whh.automaticticket.operation;

import android.content.Context;
import android.content.ServiceConnection;
import android.os.RemoteException;
import android.util.Log;

import com.sunmi.extprinterservice.ExtPrinterService;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

import cn.hx.whh.automaticticket.params.BarCodeContent;
import cn.hx.whh.automaticticket.params.BitmapContent;
import cn.hx.whh.automaticticket.params.ColumnsTextContent;
import cn.hx.whh.automaticticket.params.LineWrapContent;
import cn.hx.whh.automaticticket.params.PixEiWrapContent;
import cn.hx.whh.automaticticket.params.PrintParams;
import cn.hx.whh.automaticticket.params.QrCodeContent;
import cn.hx.whh.automaticticket.params.TextContent;

/**
 * K2  主机打印操作类
 */
public class K2Print {
    private static final byte ESC = 0x1B;// Escape
    private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    private String begin = "------------------------------------------------" + "";
    private String end = "------------------------------------------------" + "";
    private Context context;
    public String title; // 标题
    private static final String TAG = "K2Print";
    private ServiceConnection connService;

    private ExtPrinterService mPrinter;

    public ArrayList<PrintParams> params;

    private String unic = "GBK";

    /**
     * 这里应该设计成文单例模式
     * @param context
     * @param printerService
     * @param params
     */
    public K2Print(Context context, ExtPrinterService printerService,ArrayList<PrintParams> params) {
        this.context = context;
        this.mPrinter = printerService;
        this.params = params;
    }

    /**
     * 执行打印方法
     */
    public void print() {
        if (params == null || params.size() < 1) {
            Log.i(TAG, "没有打印对象");
        }
        try {
            /*
              mPrinter.getPrinterStatus(); 获取打印机状态
             -1 打印机脱机或者打印服务还未连接打印机
              0 打印机运行正常
              1 打印机开盖
              2 打印机缺纸
              3 打印机即将缺纸
              4 打印机过热
             */
            int printerStatus = mPrinter.getPrinterStatus(); // 获取打印机状态
            printerStatusStrategy(printerStatus);
            if (printerStatus != 0) {
                return;
            }

            mPrinter.lineWrap(1); // 高行走纸一行
            // TODO begin 这里是否要打印logon
            // TODO end 这里是否要打印logon
            if (title != null && !"".equals(title)) {
                mPrinter.setAlignMode(1); // 设置对齐方式  0 居左(默然) 1 居中 2居右
                mPrinter.setFontZoom(1, 1); // 设置字体大小 hori 横向大小 veri 纵向大小
                mPrinter.sendRawData(boldOn()); // 标题字体加粗
                mPrinter.printText(title);
                mPrinter.flush();
                // mPrinter.sendRawData(boldOff()); // 标题字体加粗
            }
            mPrinter.lineWrap(1); // 高行走纸一行

            mPrinter.setAlignMode(0); // 设置对齐方式  0 居左(默然) 1 居中 2居右
            mPrinter.setFontZoom(0, 0); // 设置字体大小 hori 横向大小 veri 纵向大小
            mPrinter.printText("欢迎你的光临 ······ " + sdf.format(new Date()));
            mPrinter.flush();
            mPrinter.printText(begin);
            mPrinter.flush();
            for (PrintParams entity : params) {
                switch (entity.type) {
                    case Text: // 打印文本
                        TextContent textContent = (TextContent) entity.content;
                        mPrinter.setAlignMode(0); // 设置对齐方式  0 居左(默然) 1 居中 2居右
                        mPrinter.setFontZoom(0, 0); // 设置字体大小 hori 横向大小 veri 纵向大小
                        mPrinter.printText(textContent.getText());
                        mPrinter.flush();
                        break;
                    case BarCode: // 打印条形码
                        BarCodeContent barCodeContent = (BarCodeContent) entity.content;
                        mPrinter.setAlignMode(1); // 设置对齐方式  0 居左(默然) 1 居中 2居右
                        mPrinter.setFontZoom(0, 0); // 设置字体大小 hori 横向大小 veri 纵向大小
                        mPrinter.printBarCode(barCodeContent.code, barCodeContent.type, barCodeContent.width, barCodeContent.height, barCodeContent.hriPos);
                        mPrinter.flush();
                        break;
                    case QrCode: // 打印二维码
                        QrCodeContent qrCodeContent = (QrCodeContent) entity.content;
                        mPrinter.setAlignMode(1); // 设置对齐方式  0 居左(默然) 1 居中 2居右
                        mPrinter.setFontZoom(0, 0); // 设置字体大小 hori 横向大小 veri 纵向大小
                        mPrinter.printQrCode(qrCodeContent.code, qrCodeContent.modeSize, qrCodeContent.errorLevel);
                        mPrinter.flush();
                        break;
                    case Bitmap: // 打印图片
                        BitmapContent bitmapContent = (BitmapContent) entity.content;
                        mPrinter.setAlignMode(1); // 设置对齐方式  0 居左(默然) 1 居中 2居右
                        mPrinter.setFontZoom(0, 0); // 设置字体大小 hori 横向大小 veri 纵向大小
                        mPrinter.printBitmap(bitmapContent.bitmap, bitmapContent.mode);
                        mPrinter.flush();
                        break;
                    case ColumnsText: // 打印表格
                        ColumnsTextContent columnsTextContent = (ColumnsTextContent) entity.content;
                        mPrinter.setAlignMode(1); // 设置对齐方式  0 居左(默然) 1 居中 2居右
                        mPrinter.setFontZoom(0, 0); // 设置字体大小 hori 横向大小 veri 纵向大小
                        mPrinter.printColumnsText(columnsTextContent.colsTextArr, columnsTextContent.colsWidthArr, columnsTextContent.colsAlign);
                        mPrinter.flush();
                        break;
                    case Wrap: // 打印高行走纸
                        LineWrapContent lineWrapContent = (LineWrapContent) entity.content;
                        mPrinter.lineWrap(lineWrapContent.number); // 高行走纸一行
                        break;
                    case PixEiWrap: // 打印像素走纸
                        PixEiWrapContent pixEiWrapContent = (PixEiWrapContent) entity.content;
                        mPrinter.pixelWrap(pixEiWrapContent.number);
                        break;
                    default:
                        mPrinter.setAlignMode(0); // 设置对齐方式  0 居左(默然) 1 居中 2居右
                        mPrinter.setFontZoom(1, 1); // 设置字体大小 hori 横向大小 veri 纵向大小
                        mPrinter.printText("未知的枚举类型");
                        mPrinter.flush();
                        break;
                }
            }
            mPrinter.setAlignMode(0); // 设置对齐方式  0 居左(默然) 1 居中 2居右
            mPrinter.setFontZoom(0, 0); // 设置字体大小 hori 横向大小 veri 纵向大小
            mPrinter.printText(end);
            mPrinter.flush();
            mPrinter.printText("谢谢您的使用,欢迎再次光临 " + sdf.format(new Date()));
            mPrinter.flush();
            mPrinter.lineWrap(3);
            mPrinter.cutPaper(0, 0);// 切刀切纸
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        context.unbindService(this.connService);

    }

    /**
     * 打印机状态策略
     *
     * @param printerStatus
     * @return
     */
    public String printerStatusStrategy(int printerStatus) {
        String message;
        switch (printerStatus) {
            case -1:
                message = "没有打印对象";
                Log.i(TAG, "没有打印对象");
                break;
            case 0:
                message = "打印机运行正常";
                Log.i(TAG, "打印机运行正常");
                break;
            case 1:
                message = "打印机开盖";
                Log.i(TAG, "打印机开盖");
                break;
            case 2:
                message = "打印机缺纸";
                Log.i(TAG, "打印机缺纸");
                break;
            case 3:
                message = "打印机即将缺纸";
                Log.i(TAG, "打印机即将缺纸");
                break;
            case 4:
                message = "打印机过热";
                Log.i(TAG, "打印机过热");
                break;
            default:
                message = "打印机状态未被记录";
                Log.i(TAG, "打印机状态未被记录");
                break;
        }
        return message;
    }

    /**
     * 字体加粗
     */
    private byte[] boldOn() {
        byte[] result = new byte[3];
        result[0] = ESC;
        result[1] = 69;
        result[2] = 0xF;
        return result;
    }

    /**
     * 取消字体加粗
     */
    private byte[] boldOff() {
        byte[] result = new byte[3];
        result[0] = ESC;
        result[1] = 69;
        result[2] = 0;
        return result;
    }

    public void unbindService() {
        this.unic = unic;
    }

    public void callback(K2Print k2Print, ServiceConnection connService){
        k2Print.connService = connService;
    }
}
